#include <list>
#include <tuple>
#include <vector>
#include <gtest/gtest.h>


template <typename T>
auto addOne(T t)
{
    return t + 1;
}
template <typename T>
using ParamT = std::vector<std::tuple<T,T>>;

static std::tuple < ParamT<int>,ParamT<long long>,ParamT<std::size_t>> allParams{
 {
    // Test cases for int
    std::make_tuple(1, 2),
    std::make_tuple(5, 6),
    std::make_tuple(9, 10),
  },
  {
    // Test cases for long long
    std::make_tuple(1, 2),
    std::make_tuple(5, 6),
    std::make_tuple(9, 10),
  },
  {
    // Test cases for size_t
    std::make_tuple(1, 2),
    std::make_tuple(5, 6),
    std::make_tuple(9, 10),
  },
};

template <typename T>
struct AddOneTestsFixture : public testing::Test {
  AddOneTestsFixture() : params{std::get<ParamT<T>>(allParams)} {}
  ParamT<T> params;
};

TYPED_TEST_SUITE_P(AddOneTestsFixture);

TYPED_TEST_P(AddOneTestsFixture, doAddOne) {
  for(auto const& [input, expect] : this->params) {
    ASSERT_EQ(addOne(input), expect)
      << "addOne(" << input << ") != " << expect << "!";
  }
}

REGISTER_TYPED_TEST_SUITE_P(AddOneTestsFixture, doAddOne);

using Types = testing::Types<int, long long, std::size_t>;
INSTANTIATE_TYPED_TEST_SUITE_P(TestPrefix, AddOneTestsFixture, Types);


template <typename T>
class FooTest: public ::testing::Test{
public:
    typedef std::list<T> List;
    static T shared_;
    T value_;
};

TYPED_TEST_SUITE_P(FooTest);

TYPED_TEST_P(FooTest, DoesBlah) {
    TypeParam n = 0;
}

REGISTER_TYPED_TEST_SUITE_P(FooTest,DoesBlah);
using Types = testing::Types<int,double,float,char>;
INSTANTIATE_TYPED_TEST_SUITE_P(My ,FooTest,Types);

int main(int argc,char* argv[])
{
    ::testing::InitGoogleTest(&argc,argv);
    return RUN_ALL_TESTS();
}